//召唤兽移动?

package net.sf.odinms.net.channel.handler;

import java.awt.Point;
import java.util.Arrays;
import java.util.List;

import java.util.concurrent.ScheduledFuture;

import net.sf.odinms.client.ISkill;
import net.sf.odinms.client.MapleBuffStat;
import net.sf.odinms.client.MapleCharacter;
import net.sf.odinms.client.MapleCharacter.CancelCooldownAction;
import net.sf.odinms.client.MapleClient;
import net.sf.odinms.client.MapleStat;
import net.sf.odinms.client.SkillFactory;
import net.sf.odinms.client.messages.ServernoticeMapleClientMessageCallback;
import net.sf.odinms.client.skills.*;
import net.sf.odinms.client.status.MonsterStatusEffect;
import net.sf.odinms.net.AbstractMaplePacketHandler;
import net.sf.odinms.server.MapleStatEffect;
import net.sf.odinms.server.TimerManager;
import net.sf.odinms.server.life.MapleMonster;
import net.sf.odinms.server.maps.MapleMap;
import net.sf.odinms.server.maps.MapleMapObject;
import net.sf.odinms.server.maps.MapleMapObjectType;
import net.sf.odinms.tools.MaplePacketCreator;
import net.sf.odinms.tools.data.input.SeekableLittleEndianAccessor;

public class SpecialMoveHandler extends AbstractMaplePacketHandler {

    private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(SpecialMoveHandler.class);
    @Override
    public void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
        //System.out.println("SpecialMove："+slea.toString());
        slea.readInt();
        int skillid = changeSkillId(slea.readInt(), c.getPlayer());//技能ID
        MapleCharacter chr = c.getPlayer();
        Point pos = null;
        int __skillLevel = slea.readByte();//技能等级
        ISkill skill = SkillFactory.getSkill(skillid);
        int skillLevel = chr.getSkillLevel(skill);
        MapleStatEffect effect = skill.getEffect(skillLevel);
        /*
        System.out.println("SpecialMove的技能ID："+skillid);
        System.out.println("SpecialMove的技能名字："+SkillFactory.getSkillName(skillid));
        System.out.println("SpecialMove的技能等级："+__skillLevel);
        */
        chr.resetAfkTimer();
        int beforeMp = chr.getMp();
        int 磁场数量 = 0;
        if (skillLevel == 0 || skillLevel != __skillLevel) {
            log.info("[异常] {} 玩家使用了等级异常的技能",chr.getName());
            c.disconnect();
            return;
        } else if(!chr.is能否使用进阶灵气()) {
            chr.cancelEffect(effect, true, -1);
            chr.set能否使用进阶灵气(true);
            c.getSession().write(MaplePacketCreator.enableActions());
           return;
        } else {
            if (skillid % 10000000 == 1010 || skillid % 10000000 == 1011) {
                skillLevel = 1;
                chr.setDojoEnergy(0);
                c.getSession().write(MaplePacketCreator.getEnergy(0));
        }
        
        if (effect.getCooldown() > 0) { //如果有冷却时间
            if (chr.skillisCooling(skillid)) {
                return;
            } else {
                if (skillid != 枪手.武装
                        || 
                        (skillid == 机械师.磁场 
                        && chr.getSummons().get(机械师.磁场).size() == 2)
                        ) { //武装不设置冷却时间
                    c.getSession().write(MaplePacketCreator.skillCooldown(skillid, effect.getCooldown()));
                    ScheduledFuture<?> timer = TimerManager.getInstance().schedule(new CancelCooldownAction(chr, skillid), effect.getCooldown() * 1000);
                    chr.addCooldown(skillid, System.currentTimeMillis(), effect.getCooldown() * 1000, timer);
                }
            }
        }
        switch (skillid) {
            case 勇士.磁石://磁石
            //case 1221001://磁石 取消圣骑士磁石
            case 龙骑.磁石://磁石
                int num = slea.readInt();
                int mobId;
                byte success;
                for (int i = 0; i < num; i++) {
                    mobId = slea.readInt();
                    success = slea.readByte();
                    chr.getMap().broadcastMessage(chr, MaplePacketCreator.showMagnet(mobId, success), false);
                    MapleMonster monster = chr.getMap().getMonsterByOid(mobId);
                    if (monster != null) {
                        monster.switchController(chr, monster.isControllerHasAggro());
                    }
                }
                byte direction = slea.readByte();
                chr.getMap().broadcastMessage(chr, MaplePacketCreator.showBuffeffect(chr.getId(), skillid, 1, direction), false);
                c.getSession().write(MaplePacketCreator.enableActions());
                break;   
        }
        MapleStatEffect ret = new MapleStatEffect();//定义角色效果ret
        ret.setSourceId(skillid);
        if (ret.isMonsterRiding()) {
            //log.info("执行了SpecialMove 属于骑宠技能");
            slea.readShort();
        }
        if(skillid == 双刀.怪物炸弹 || skillid == 标飞.忍者伏击 || skillid == 刀飞.忍者伏击) { //怪物炸弹 忍者伏击
            int hasMonster = slea.readByte();
            boolean isPoison = false;
            if(skillid == 标飞.忍者伏击 || skillid == 刀飞.忍者伏击)
                isPoison = true;
            if(hasMonster > 0){
                for(int i = 0; i < hasMonster; i++) {
                    int mobid = slea.readInt();//怪的Object id
                    MapleMonster monster = c.getPlayer().getMap().getMonsterByOid(mobid);
                    MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(effect.getMonsterStati(), skill, false);
                    monster.applyStatus(chr, monsterStatusEffect, isPoison, effect.getDuration());
                }
            }
        } else if (skillid == 弩骑.吞噬) {
            //log.info("吞噬技能");
            MapleMonster monster = c.getPlayer().getMap().getMonsterByOid(c.getPlayer().获得吞噬的怪的id());
            if (monster != null) {
                monster.switchController(chr, monster.isControllerHasAggro());
            }
            c.getPlayer().getMap().killMonster2(monster, chr);
        } else if (slea.available() >= 5) {
            if(skillid == 机械师.磁场)
                磁场数量 = slea.readByte(); //0 - 第一个磁场 1 - 第二个磁场 2 - 第三个磁场[召唤磁场效果]
            if(磁场数量 == 2) 
                pos = new Point(c.getPlayer().getPosition());
            else 
                pos = new Point(slea.readShort(), slea.readShort());
            //log.info("执行了SpecialMove的坐标设置："+pos);
            //log.info("实际的人物坐标："+c.getPlayer().getPosition());
        } 
       
        if(skillid == 机械师.加速器) {
            MapleMap map = c.getPlayer().getMap();
            double range = Double.POSITIVE_INFINITY;
            List<MapleMapObject> monsters = map.getMapObjectsInRange(c.getPlayer().getPosition(), range, Arrays.asList(MapleMapObjectType.MONSTER));
            for (MapleMapObject monstermo : monsters) {
                MapleMonster monster = (MapleMonster) monstermo;
                MonsterStatusEffect monsterStatusEffect = new MonsterStatusEffect(effect.getMonsterStati(), skill, false);
                monster.applyStatus(chr, monsterStatusEffect, false, effect.getDuration());
            }
        }
        if (chr.isAlive()) {
            if (skillid == 管理员.隐藏术 && chr.isGM())
                chr.setHidden(!chr.isHidden());
            else if(skillid == 战法.进阶黑暗灵气 || skillid == 战法.进阶蓝色灵气 || skillid == 战法.进阶黄色灵气)
                chr.set能否使用进阶灵气(false);
            if (skill.getId() != 牧师.时空门 || chr.canDoor()) {
                effect.applyTo(chr, pos); //给buff
                if(skillid == 机械师.磁场 && 磁场数量 == 2) {
                    //产生磁场
                    /*
                    c.getSession().write(MaplePacketCreator.召唤磁场(chr.getId(), 
                            chr.getSummons().get(机械师.磁场).get(0).getObjectId(), 
                            chr.getSummons().get(机械师.磁场).get(1).getObjectId(), 
                            chr.getSummons().get(机械师.磁场).get(2).getObjectId()));
                    */
                    chr.getMap().broadcastMessage(MaplePacketCreator.召唤磁场(chr.getId(), 
                            chr.getSummons().get(机械师.磁场).get(0).getObjectId(), 
                            chr.getSummons().get(机械师.磁场).get(1).getObjectId(), 
                            chr.getSummons().get(机械师.磁场).get(2).getObjectId()));
                } else if(skillid == 双刀.傀儡召唤){ //傀儡召唤 用时会取消镜像分身
                    skill = SkillFactory.getSkill(双刀.镜像分身);
                    effect = skill.getEffect(chr.getSkillLevel(skill));
                    chr.cancelEffect(effect, false, -1);
                } else if(skillid == 战神.斗气重生) {
                    //y项 50 + 5 * x
                    int combo = 5 + skillLevel / 2;
                    int comboCount = 50 + 5 * skillLevel;
                    SkillFactory.getSkill(战神.矛连击强化).getEffect(combo > 10 ? 10 : combo).applyTo(chr);
                    chr.setCombo(comboCount);
                    chr.getClient().getSession().write(MaplePacketCreator.Combo_Effect(comboCount));
                }
                if (skill.getId() != 牧师.群体治愈 && effect != null && effect.getMpCon() != 0) { //群体治愈
                    if (chr.getMp() - beforeMp < skill.getEffect(skillLevel).getMpCon()) {
                        int remainingMp = beforeMp - skill.getEffect(skillLevel).getMpCon();
                        chr.setMp(remainingMp);
                        chr.updateSingleStat(MapleStat.MP, remainingMp);
                    }
                }
            } else if(!chr.canDoor()) {
                new ServernoticeMapleClientMessageCallback(5, c).dropMessage("请等候5秒再使用时空门!");
                c.getSession().write(MaplePacketCreator.enableActions());
            }
        }
        c.getSession().write(MaplePacketCreator.enableActions());
        }
    }
    
    
    public int changeSkillId(int skillid, MapleCharacter chr) {
        int a = skillid;
        if(skillid == 机械师.金属机甲_重机枪 && chr.getBuffedValue(MapleBuffStat.机械师) != null)
            a = 35121013;
        else if(skillid == 战法.黑暗灵气 && chr.getSkillLevel(战法.进阶黑暗灵气) > 0)
            a = 战法.进阶黑暗灵气;
        else if(skillid == 战法.蓝色灵气 && chr.getSkillLevel(战法.进阶蓝色灵气) > 0)
            a = 战法.进阶蓝色灵气;
        else if(skillid == 战法.黄色灵气 && chr.getSkillLevel(战法.进阶黄色灵气) > 0)
            a = 战法.进阶黄色灵气;
        return a;
    }
}

    
